﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

using BizElements.Core;
using BizElements.TemplateEngine;

namespace BizElements.Generator
{
    static class GenUtil
    {
        public const string DefaultFileExtension = "cs";

        public static string GetDuration(DateTime start)
        {
            TimeSpan duration = DateTime.Now - start;
            return duration.ToString();
        }

        public static string GetOutputSubdirectoryVariable(ITemplate template)
        {
            string subdir = template.GetVariable(SpecialVariable.OutputSubdirectory);
            if (string.IsNullOrEmpty(subdir))
                return null;

            subdir = subdir.Trim();
            // Remove tailing backslash.
            if (subdir[subdir.Length - 1] == '\\')
                subdir = subdir.Substring(0, subdir.Length - 1);

            if (subdir.Contains("{0}"))
            {
                string solutionNamespace = template.GetVariable(SpecialVariable.SolutionNamespace) ?? "";
                subdir = subdir.Replace("{0}", solutionNamespace);
            }

            return subdir;
        }

        public static bool ShouldWriteToSingleFile(ITemplate template)
        {
            return !string.IsNullOrEmpty(template.GetVariable(SpecialVariable.SingleFile)) || !string.IsNullOrEmpty(template.GetSetting(SpecialVariable.SingleFile));
        }

        public static string CreateClassOutputFilePath(string objName, Type objType, ITemplate template, string outputFolder)
        {
            string fileName = objName ?? objType.Name;
            string nameSuffix = template.GetVariable(SpecialVariable.FileNameSuffix) ?? template.GetSetting(SpecialVariable.FileNameSuffix);
            string extension = template.GetSetting(SpecialVariable.FileExtension) ?? DefaultFileExtension;
            string subdir = GenUtil.GetOutputSubdirectoryVariable(template);
            string filePath;
            if (string.IsNullOrEmpty(subdir))
                filePath = string.Format("{0}{1}{2}.{3}", outputFolder, fileName, nameSuffix, extension);
            else
                filePath = string.Format("{0}{1}\\{2}{3}.{4}", outputFolder, subdir, fileName, nameSuffix, extension);

            return filePath;
        }

        public static string GetSingleFieldVariableOrSetting(ITemplate template)
        {
            string fileWithExt = template.GetVariable(SpecialVariable.SingleFile) ?? template.GetSetting(SpecialVariable.SingleFile);
            if (string.IsNullOrEmpty(fileWithExt))
                return null;

            fileWithExt = fileWithExt.Trim();
            if (fileWithExt.Contains("{0}"))
            {
                string solutionNamespace = template.GetVariable(SpecialVariable.SolutionNamespace) ?? "";
                fileWithExt = fileWithExt.Replace("{0}", solutionNamespace);
            }

            return fileWithExt;
        }

        public static string CreateSingleFilePathForTemplate(ITemplate template, string outputFolder, string file)
        {
            string subdir = GenUtil.GetOutputSubdirectoryVariable(template);
            string filePath;
            if (string.IsNullOrEmpty(subdir))
                filePath = string.Format("{0}{1}", outputFolder, file);
            else
                filePath = string.Format("{0}{1}\\{2}", outputFolder, subdir, file);

            return filePath;
        }

        public static List<ITemplate> GetMultiFileTemplates(IEnumerable itemTemplates)
        {
            List<ITemplate> multiFileTemplates = new List<ITemplate>();
            foreach (ITemplate temp in itemTemplates)
            {
                if (!ShouldWriteToSingleFile(temp))
                    multiFileTemplates.Add(temp);
            }

            return multiFileTemplates;
        }

        public static List<ITemplate> GetSingleFileTemplates(IEnumerable itemTemplates)
        {
            List<ITemplate> singleFileTemplates = new List<ITemplate>();
            foreach (ITemplate temp in itemTemplates)
            {
                if (ShouldWriteToSingleFile(temp))
                    singleFileTemplates.Add(temp);
            }

            return singleFileTemplates;
        } 
    }
}
